/**
 * 
 */
package com.qunar.mina.app.service.impl;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.util.NumericUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.qunar.mina.app.service.IndexService;
import com.qunar.mina.app.utils.WriterUtils;
import com.qunar.wireless.ugc.qcfclient.dto.Address;

/**
 * @author tao.zhang
 */
public class Indexer implements IndexService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /** 创建全部索引 */
    @Override
    public void createAllIndex() {
        try {
            IndexWriter fsAddressWriter = WriterUtils.getFsAddressWriter();
            fsAddressWriter.deleteAll();
            fsAddressWriter.commit();

            IndexWriter fsUserWriter = WriterUtils.getUserWriter();
            fsUserWriter.deleteAll();
            fsUserWriter.commit();

            IndexWriter fsAuditorWriter = WriterUtils.getAuditorWriter();
            fsAuditorWriter.deleteAll();
            fsAuditorWriter.commit();

            IndexWriter fsRecWriter = WriterUtils.getRecWriter();
            fsRecWriter.deleteAll();
            fsRecWriter.commit();

            IndexWriter fsAlbumWriter = WriterUtils.getAlbumcWriter();
            fsAlbumWriter.deleteAll();
            fsAlbumWriter.commit();

            WriterUtils.addAddressDocs(fsAddressWriter);
            WriterUtils.addRecordDocs(fsRecWriter);
            WriterUtils.addUserDocs(fsUserWriter);
            WriterUtils.addAuditorDocs(fsAuditorWriter);
            WriterUtils.addAlbumDocs(fsAlbumWriter);

            logger.info("创建索引成功……");

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

    }

    /*
     * 添加索引
     */
    @Override
    public void addIndex(Object o, String writerName) {

        if (o == null) {
            logger.info("【Indexer.addIndex】add Index error: o is null ");
            return;
        }
        try {
            Document doc = WriterUtils.object2Document(o);
            IndexWriter fsIndexWriter = null;
            fsIndexWriter = WriterUtils.getWriter(writerName);
            if (fsIndexWriter == null) {
                logger.error("writerName不正确 ,fsIndexWriter为空！");
                return;
            }
            long start = System.currentTimeMillis();
            fsIndexWriter.addDocument(doc);
            fsIndexWriter.commit();
            long end = System.currentTimeMillis();
            logger.info("【Indexer.addIndex】 add index success. Spend time: " + (end - start) + "ms");
        } catch (IOException e) {
            logger.error("【Indexer.addIndex】 add index error");
            logger.error(e.getMessage(), e);
        }

    }

    /*
     * 批量添加索引
     */
    @Override
    public void batchAddIndex(List<?> list, String writerName) {

        if (list.size() > 200) {
            return;
        }

        IndexWriter fsIndexWriter = null;
        try {
            fsIndexWriter = WriterUtils.getWriter(writerName);
            long start = System.currentTimeMillis();

            for (Iterator iterator = list.iterator(); iterator.hasNext();) {
                Object o = (Object) iterator.next();
                Document doc = WriterUtils.object2Document(o);
                fsIndexWriter.addDocument(doc);
            }
            fsIndexWriter.commit();
            long end = System.currentTimeMillis();
            logger.info("【Indexer.batchAddIndex】 add index success. Spend time:" + (end - start) + "ms");
        } catch (Exception e) {
            logger.error("【Indexer.batchAddIndex】 add index error");
            logger.error(e.getMessage(), e);
        }

    }

    /*
     * 删除索引
     */
    @Override
    public void delIndex(String writerName, Term term) {

        if (term == null) {
            logger.info("【Indexer.delIndex】add Index error: o is null ");
            return;
        }

        try {
            IndexWriter fsWriter = null;
            fsWriter = WriterUtils.getWriter(writerName);
            long start = System.currentTimeMillis();
            fsWriter.deleteDocuments(term);
            fsWriter.commit();
            long end = System.currentTimeMillis();
            logger.info("【Indexer.delIndex】del Index success. Spend time:" + (end - start) + "ms");
        } catch (Exception e) {
            logger.error("【Indexer.delIndex】 del index error");
            logger.error(e.getMessage(), e);
        }

    }

    /*
     * 批量删除
     */
    @Override
    public void batchDelIndex(String writerName, Term... terms) {
        IndexWriter fsWriter = null;

        if (null == terms) {
            logger.info("【Indexer.batchDelIndex】batchDel index error: list is null or size = 0 ");
            return;
        }

        try {
            fsWriter = WriterUtils.getWriter(writerName);
            long start = System.currentTimeMillis();
            fsWriter.deleteDocuments(terms);
            fsWriter.commit();
            long end = System.currentTimeMillis();
            logger.info("【Indexer.batchDelIndex】batchDel index success. Spend time:" + (end - start) + "ms");
        } catch (Exception e) {
            logger.error("【Indexer.batchDelIndex】 batchDel index error");
            logger.error(e.getMessage(), e);
        }

    }

    /*
     * 更新索引,单次最大200条
     */
    @Override
    public void batchUpdateIndex(List<?> list, String writerName, Term... terms) {

        if (list == null || list.size() == 0) {
            logger.info("【Indexer.batchUpdateIndex】batchUpdate index error: list is null or size = 0 ");
            return;
        }
        if (list.size() > 200) {
            logger.info("【Indexer.batchUpdateIndex】 error: list number is too large! ");
            return;
        }
        try {
            long start = System.currentTimeMillis();
            /** 先批量删除索引 */
            this.batchDelIndex(writerName, terms);
            /** 再批量添加索引 */
            this.batchAddIndex(list, writerName);
            long end = System.currentTimeMillis();
            logger.info("【Indexer.batchUpdateIndex】batchUpdate index success. Spend time:" + (end - start) + "ms");
        } catch (Exception e) {
            logger.error("【Indexer.batchUpdateIndex】 batchUpdate index error");
            logger.error(e.getMessage(), e);
        }

    }

    /*
     * 更新索引
     */
    @Override
    public void updateIndex(Object o, String writerName, Term term) {

        if (null == o) {
            logger.info("【Indexer.updateIndex】add Index error: o is null ");
            return;
        }
        IndexWriter fsWriter = null;
        try {
            fsWriter = WriterUtils.getWriter(writerName);
            long start = System.currentTimeMillis();
            Document doc = WriterUtils.object2Document(o);
            fsWriter.updateDocument(term, doc);
            fsWriter.commit();
            long end = System.currentTimeMillis();
            logger.info("【Indexer.updateIndex】update index success. Spend time:" + (end - start) + "ms");
        } catch (Exception e) {
            logger.error("【Indexer.updateIndex】 update index error");
            logger.error(e.getMessage(), e);
        }

    }

}
